package com.wxzhou.wangzhuan.api;

import com.wxzhou.wangzhuan.dto.CommonRequestDto;
import com.wxzhou.wangzhuan.dto.LoginResponseDto;
import com.wxzhou.wangzhuan.dto.ResponseDto;
import com.wxzhou.wangzhuan.dto.UserInfoDto;
import com.wxzhou.wangzhuan.security.UserContext;
import com.wxzhou.wangzhuan.service.AuthService;
import io.quarkus.security.Authenticated;
import io.smallrye.mutiny.Uni;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.jboss.logging.Logger;

import java.util.Map;
import java.util.Optional;

/**
 * 用户认证控制器
 */
@Path("/api/auth")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class AuthApi {

    private static final Logger LOG = Logger.getLogger(AuthApi.class);

    @Inject
    AuthService authService;

    @Inject
    UserContext userContext;

    /**
     * 设备登录
     */
    @POST
    @Path("/device-login")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(summary = "设备登录", description = "通过设备ID进行匿名登录")
    public Uni<Response> deviceLogin(
            @Valid CommonRequestDto baseInfo,
            @HeaderParam("device-id") String deviceId,
            @HeaderParam("channel") String channel) {

        if (deviceId == null || deviceId.trim().isEmpty()) {
            ResponseDto<Object> error = ResponseDto.error("设备ID不能为空");
            return Uni.createFrom().item(Response.status(error.getCode()).entity(error).build());

        }

        if (channel == null || channel.trim().isEmpty()) {
            ResponseDto<Object> error = ResponseDto.error("channel不能为空");
            return Uni.createFrom().item(Response.status(error.getCode()).entity(error).build());
        }


//        validUserAndDevice(); //强制校验用户携带设备、channel才可以访问接口接口

        return authService.deviceLogin(deviceId,channel)
                .onItem().transform(response -> {
                    if (response != null) {
                        ResponseDto<LoginResponseDto> resp = ResponseDto.success(response);
                        return Response.ok(resp).build();
                    } else {
                        ResponseDto<Map<String, Object>> resp = ResponseDto.fail("登录失败");
                        return Response.status(401).entity(resp).build();
                    }
                }).onFailure().recoverWithItem(throwable -> {
                            LOG.errorf(throwable,"登录失败");
                            ResponseDto<Map<String, Object>> resp = ResponseDto.error("登录失败,错误代码500");
                            return Response.status(500).entity(resp).build();
                        }
                );
    }

    /**
     * 退出登录
     */
    @POST
    @Path("/logout")
    @Authenticated
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(summary = "退出登录", description = "用户退出登录，清除认证状态")
    public Uni<ResponseDto<String>> logout(
            @Parameter(description = "认证令牌", required = true, example = "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
            @HeaderParam("Authorization") String authHeader) {
        String token = extractToken(authHeader);
        LOG.info("用户退出登录 | token= " + token);

        return authService.logout(token)
                .onItem().transform(result -> ResponseDto.success("退出登录成功"))
                .onFailure().invoke(throwable -> {
                    LOG.error("退出登录失败 | username= " + token, throwable);
                })
                .onFailure().recoverWithItem(throwable ->
                        ResponseDto.error("退出登录失败: " + throwable.getMessage())
                );
    }

    /**
     * 获取用户信息
     */
    @POST
    @Path("/user-info")
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(summary = "获取用户信息", description = "获取当前登录用户的详细信息")
    public Uni<Response> getUserInfo(CommonRequestDto dto) {
        // 安全地获取用户信息
        Optional<UserInfoDto> userInfoOpt = userContext.getCurrentUserInfo();
        if (userInfoOpt.isEmpty()) {
            ResponseDto<UserInfoDto> resp = ResponseDto.unauthorized("用户未登录");
            return Uni.createFrom().item(Response.status(Response.Status.UNAUTHORIZED).entity(resp).build());
        }
        ResponseDto<UserInfoDto> resp = ResponseDto.success(userInfoOpt.get());
        return Uni.createFrom().item(Response.ok(resp).build());


//        String userId = securityIdentity.getPrincipal().getName();
//        LOG.info("获取用户信息 | userId={}", userId);
//
//        return authService.getUserInfo(userId)
//                .onItem().transform(userInfo -> ResponseDto.success(userInfo))
//                .onFailure().invoke(throwable -> {
//                    LOG.error("获取用户信息失败 | userId={}, error={}", userId, throwable.getMessage());
//                    throwable.printStackTrace();
//                })
//                .onFailure().recoverWithItem(throwable ->
//                    ResponseDto.error("获取用户信息失败: " + throwable.getMessage())
//                );
    }

    /**
     * 从Authorization头中提取token
     */
    private String extractToken(String authHeader) {
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7);
        }
        return null;
    }
} 